<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Listen / Notify</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"/><link rel="home" href="index.html" title="The PostgreSQL™ JDBC Interface"/><link rel="up" href="ext.html" title="Chapter 9. PostgreSQL™ Extensions to the JDBC API"/><link rel="prev" href="largeobjects.html" title="Large Objects"/><link rel="next" href="server-prepare.html" title="Server Prepared Statements"/></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Listen / Notify</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="largeobjects.html">Prev</a> </td><th width="60%" align="center">Chapter 9. <span class="productname">PostgreSQL</span>™ Extensions to the
    <acronym class="acronym">JDBC</acronym> <acronym class="acronym">API</acronym></th><td width="20%" align="right"> <a accesskey="n" href="server-prepare.html">Next</a></td></tr></table><hr/></div><div class="sect1" title="Listen / Notify"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="listennotify"/>Listen / Notify</h2></div></div></div><p>
    Listen and Notify provide a simple form of signal or interprocess
    communication mechanism for a collection of processes accessing
    the same <span class="productname">PostgreSQL</span>™ database.  For more
    information on notifications consult the main server documentation.
    This section only deals with the <acronym class="acronym">JDBC</acronym> specific
    aspects of notifications.
   </p><p>
    Standard <code class="literal">LISTEN</code>, <code class="literal">NOTIFY</code>, and
    <code class="literal">UNLISTEN</code> commands are issued via the
    standard <code class="classname">Statement</code> interface.  To retrieve
    and process retrieved notifications the
    <code class="classname">Connection</code> must be cast to the
    <span class="productname">PostgreSQL</span>™ specific extension interface
    <code class="classname">PGConnection</code>.  From there the
    <code class="function">getNotifications()</code> method can be used to retrieve
    any outstanding notifications.
   </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
     A key limitation of the <acronym class="acronym">JDBC</acronym> driver is that it
     cannot receive asynchronous notifications and must poll the
     backend to check if any notifications were issued.  
    </p></div><div class="example"><a id="listen-notify-example"/><p class="title"><b>Example 9.2. Receiving Notifications</b></p><div class="example-contents"><pre class="programlisting">
import java.sql.*;

public class NotificationTest {

	public static void main(String args[]) throws Exception {
		Class.forName("org.postgresql.Driver");
		String url = "jdbc:postgresql://localhost:5432/test";

		// Create two distinct connections, one for the notifier
		// and another for the listener to show the communication
		// works across connections although this example would
		// work fine with just one connection.
		Connection lConn = DriverManager.getConnection(url,"test","");
		Connection nConn = DriverManager.getConnection(url,"test","");

		// Create two threads, one to issue notifications and
		// the other to receive them.
		Listener listener = new Listener(lConn);
		Notifier notifier = new Notifier(nConn);
		listener.start();
		notifier.start();
	}

}

class Listener extends Thread {

	private Connection conn;
	private org.postgresql.PGConnection pgconn;

	Listener(Connection conn) throws SQLException {
		this.conn = conn;
		this.pgconn = (org.postgresql.PGConnection)conn;
		Statement stmt = conn.createStatement();
		stmt.execute("LISTEN mymessage");
		stmt.close();
	}

	public void run() {
		while (true) {
			try {
				// issue a dummy query to contact the backend
				// and receive any pending notifications.
				Statement stmt = conn.createStatement();
				ResultSet rs = stmt.executeQuery("SELECT 1");
				rs.close();
				stmt.close();

				org.postgresql.PGNotification notifications[] = pgconn.getNotifications();
				if (notifications != null) {
					for (int i=0; i&lt;notifications.length; i++) {
						System.out.println("Got notification: " + notifications[i].getName());
					}
				}

				// wait a while before checking again for new
				// notifications
				Thread.sleep(500);
			} catch (SQLException sqle) {
				sqle.printStackTrace();
			} catch (InterruptedException ie) {
				ie.printStackTrace();
			}
		}
	}

}

class Notifier extends Thread {

	private Connection conn;

	public Notifier(Connection conn) {
		this.conn = conn;
	}

	public void run() {
		while (true) {
			try {
				Statement stmt = conn.createStatement();
				stmt.execute("NOTIFY mymessage");
				stmt.close();
				Thread.sleep(2000);
			} catch (SQLException sqle) {
				sqle.printStackTrace();
			} catch (InterruptedException ie) {
				ie.printStackTrace();
			}
		}
	}

}
</pre></div></div><br class="example-break"/></div><div class="navfooter"><hr/><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="largeobjects.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ext.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="server-prepare.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Large Objects </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Server Prepared Statements</td></tr></table></div></body></html>